#include"doRegiseterOrLogin.h"
#include"initTcp.h"

#pragma pack(1)
int getParameterMap(protocol_server protocol, HashMap *map)
{
	printf("start getParameterMap\n");
	int paraNum = protocol._num;
	char *dataCopy = strdup(protocol._data); // 复制原数据，避免修改
	if (!dataCopy) {
		perror("strdup failed");
		return -1;
	}

	char *array[10] = { 0 };
	char *temp = strtok(dataCopy, "&");
	for (int i = 0; i < paraNum && temp; i++) {
		array[i] = temp;
		temp = strtok(NULL, "&");
	}

	for (int j = 0; j < paraNum; j++) {
		temp = array[j];
		if (!temp)
			continue;

		char *key = strtok(temp, "=");
		char *value = strtok(NULL, "=");

		if (key && value) {
			insert(&map, strdup(key),
			       strdup(value)); // 复制 key 和 value
		}
	}

	free(dataCopy); // 释放复制的数据
	return paraNum;
}
// 拼接key=value数据
int stringCat(char *buf, char *key, char *value)
{
	strcat(buf, key);
	strcat(buf, "=");
	strcat(buf, value);

	return 0;
}

void doRegiseterOrLogin(client_state_t *client_state)
{
	char choose;

	while (1) {
		printf("LOGIN or REGISTER:\n");
		printf("R - Register\n");
		printf("L - Login\n");
		printf("Q - Quit\n");
		printf("Enter your choice: ");

		// 清除输入缓冲区
		while ((choose = getchar()) != '\n' && choose != EOF);

		// 读取用户输入
		choose = getchar();

		// 清除输入缓冲区中的多余字符
		while (getchar() != '\n');

		switch (choose) {
		case 'R':
		case 'r':
            
			doRegister(client_state);
			return;
		case 'L':
		case 'l':
			doLogin(client_state);
			return;
		case 'Q':
		case 'q':
			printf("Exiting...\n");
			exit(EXIT_SUCCESS);
		default:
			printf("Invalid choice. Please try again.\n");
			break;
		}
	}
}

int doRegister(client_state_t *client_state)
{
	char username[100] = { 0 };
    while(1)
    {
        printf("Please enter your name: ");
        fflush(stdout);
        scanf("%s", username);
	    // 读掉换行
        char c;
        scanf("%c", &c);
        //传输username
        protocol_client client;
        memset(&client, 0, sizeof(client));
        stringCat(client._data, "username", username);
        client._cmdType = REGISTER_USERNAME;
        client._length = strlen(client._data);
        client._num = 1;
        client._flag = 1;
        printf("size:%d\n",sizeof(client));

        printf("Sending data:\n");
        printf("cmdType: %d\n", client._cmdType);
        printf("data: %s\n", client._data);
        printf("num: %d\n", client._num);
        printf("length: %d\n", client._length);

	    int send_len = sizeof(int) * 4 + client._length;
        printf("send_len:%d\n",send_len);
        //发送大小
        ssize_t send_ret1 = send(client_state->_netfd, &send_len, sizeof(int), MSG_NOSIGNAL);
        //发送内容
        ssize_t send_ret2 = send(client_state->_netfd, &client, send_len, MSG_NOSIGNAL);
        if (send_ret1 == -1 || send_ret2 == -1) {
            printf("RECONNECTING...\n");
            initTcp(&client_state->_netfd, getKey(client_state->_map, "ip"), getKey(client_state->_map, "port"));

            send(client_state->_netfd, &send_len, sizeof(int), MSG_NOSIGNAL);
            send(client_state->_netfd, &client, send_len, MSG_NOSIGNAL);
        }
        //接收服务器消息，确认用户是否已被注册
        protocol_server server;
        memset(&server, 0, sizeof(protocol_server));
        int recv_len = 0;
        recv(client_state->_netfd, &recv_len, sizeof(int), MSG_WAITALL);

        recv(client_state->_netfd, &server, recv_len, MSG_WAITALL);
        if(server._status == -1)
        {
            printf("User already exists, please try again.\n");
            continue;
        }
        else if (server._status == 0)
        {
            printf("Register name success.\n");
            break;
        }
    }
    char password[100]; 
     
    printf("Please enter your password: \n");
    fflush(stdout);
    scanf("%s", password);
    // 读掉换行
    char c;
    scanf("%c", &c);

    // 构建传输协议内容
    protocol_client client;
    memset(&client, 0, sizeof(client));

    client._cmdType = REGISTER_PASSWORD;
    client._flag = 1; 
    stringCat(client._data, "username", username);
    strcat(client._data, "&");
       stringCat(client._data, "password", password);
       client._length = strlen(client._data);
       client._num = 2;
    
       int send_len = sizeof(int) * 4 + client._length;
       //发送大小
       ssize_t send_ret1 =
        send(client_state->_netfd, &send_len, sizeof(int), MSG_NOSIGNAL);
       //发送内容
       ssize_t send_ret2 =
        send(client_state->_netfd, &client, send_len, MSG_NOSIGNAL);
       if (send_ret1 == -1 || send_ret2 == -1) {
	    printf("RECONNECTING...\n");
	    initTcp(&client_state->_netfd, getKey(client_state->_map, "ip"),
		    getKey(client_state->_map, "port"));

	    send(client_state->_netfd, &send_len, sizeof(int), MSG_NOSIGNAL);
	    send(client_state->_netfd, &client, send_len, MSG_NOSIGNAL);
    }

    // 读取服务端的返回信息, 判断是否是有这个注册的用户名字
    int msgLen = 0;
    recv(client_state->_netfd, &msgLen, sizeof(int), MSG_WAITALL);

    protocol_server server;
    bzero(&server, sizeof(server));
    recv(client_state->_netfd, &server, msgLen, MSG_WAITALL);

    if (server._status == 0) {
	    printf("REGISTER SUCCESS \n");
	    return 0;
    } else {
	    printf("ERROR: REGISTER FAILED \n");
	    return -1;
    }
}

int doLogin(client_state_t *client_state)
{
	// 输入用户名
	printf("Please enter your username: ");
	fflush(stdout);
	char username[100] = { 0 };
	fgets(username, sizeof(username), stdin);
	username[strcspn(username, "\n")] = 0; // 移除换行符

	// 输入密码
	printf("password: ");
	fflush(stdout);
	char password[100] = { 0 };
	fgets(password, sizeof(password), stdin);
	password[strcspn(password, "\n")] = 0; // 移除换行符
	printf("\n");

	// 准备协议，准备登录
	protocol_client client;
	memset(&client, 0, sizeof(client));

	snprintf(client._data, sizeof(client._data), "username=%s&password=%s",
		 username, password);
	client._length = strlen(client._data);
	client._cmdType = LOGIN;
	client._num = 2;
	client._flag = 1;

	// 发送协议
	int send_len = sizeof(int) * 4 + client._length;
	ssize_t send_ret1 = send(client_state->_netfd, &send_len, sizeof(int),
				 MSG_NOSIGNAL);
	if (send_ret1 == -1) {
		perror("send error: send_len");
		return -1;
	}

	ssize_t send_ret2 =
		send(client_state->_netfd, &client, send_len, MSG_NOSIGNAL);
	if (send_ret2 == -1) {
		perror("send error: client data");
		return -1;
	}
	printf("data transmit success\n");
	// 接收服务器消息
	protocol_server server;
	memset(&server, 0, sizeof(protocol_server));
    int recv_len = 0;
	ssize_t recv_ret1 =
		recv(client_state->_netfd, &recv_len, sizeof(int), MSG_WAITALL);
	if (recv_ret1 == -1 || recv_ret1 == 0) {
		printf("Failed to receive length or connection closed.\n");
		return -1;
	}

	ssize_t recv_ret2 =
		recv(client_state->_netfd, &server, recv_len, MSG_WAITALL);
	if (recv_ret2 == -1 || recv_ret2 == 0) {
		printf("Failed to receive protocol_server data.\n");
		return -1;
	}

	if (server._status == -1) {
		printf("Login failed, please try again.\n");
		return -1;
	}
    printf("recv_len:%d\n",server._length);
    printf("recv_data:%s\n",server._data);
    printf("recv_status:%d\n",server._status);
    printf("recv_num:%d\n",server._num);
    printf("recv_flag:%d\n", server._flag);
    printf("RECV SUCCESS\n");
    // 获取 TOKEN

    HashMap *map = createHashMap();
    if(!map)
    {
        printf("createHashMap failed\n");
        return -1;
    }
    printf("createHashMap success\n");
    
	getParameterMap(server, map);
    
	char *token = getKey(map, "token");
	if (token == NULL) {
		printf("Token not found.\n");
		return -1;
	}
    printf("token:%s\n", token);
	
	snprintf(client_state->_token, sizeof(client_state->_token), "%s",
		 token);
	client_state->_token_len = strlen(client_state->_token);
	client_state->_isLogin = 1;
	snprintf(client_state->_username, sizeof(client_state->_username), "%s",
		 username);
	printf("token:%s\n", client_state->_token);
	printf("getToken success\n");
	free(token);
	printf("Login success.\n");
	return 0;
}